package com.g2.g2zuulgateway.filter;


import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

/**
 * pre类型过滤器
 * 可以在请求被路由之前调用。适用于身份认证的场景
 */
public class AccessFilter extends ZuulFilter {
    private static Logger log = LoggerFactory.getLogger(AccessFilter.class);

    /**
     * filterType 返回过滤器类型
     * 他决定了过滤器在请求的哪个生命周期中执行。这里定义为pre，代表会在请求被路由前执行。
     *
     * pre:请求执行之前filter
     * route: 处理请求，进行路由
     * post: 请求处理完成后执行的filter
     * error:出现错误时执行的filter
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * filterOrder 返回过滤器的执行顺序
     * 当请求在一个阶段有多个过滤器是，需要根据该方法的返回值来依次执行
     * @return
     */
    @Override
    public int filterOrder() {
        return 1;
    }

    /**
     * shouldFilter 判断该过滤器是否需要被执行
     * 这里直接返回true，表示该过滤器对所有请求都会生效。
     * 实际运用中我们可以利用该函数指定过滤器的有效范围
     */
    @Override
    public boolean shouldFilter() {
        RequestContext cxt = RequestContext.getCurrentContext();
        HttpServletRequest request = cxt.getRequest();
        //忽略大小写,返回true则拦截，进入run方法(可以自定义过滤器有效范围)
//        if("/book/checked-out".equalsIgnoreCase(request.getRequestURI())){
//            return true;
//        }else if ("/book/available".equalsIgnoreCase(request.getRequestURI())){
//            return true;
//        }
        return true;
    }

    /*
     * 过滤器的具体逻辑
     * 这里我们通过ctx.setSendZuulResponse(false)让zuul过来请求，不对其进行路由
     * 然后通过ctx.setResponseStatusCode(401)设置了返回的错误码
     */
    @Override
    public Object run() {
        log.info("access filter");
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String token = request.getParameter("token");
        System.out.println("token令牌 -- ：" + token);
        log.info("send {} request to {}", request.getMethod(),request.getRequestURL().toString());
        if(token == null || token.isEmpty()) {
            log.info("令牌不存在，请进行认证");
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(401);
            //TODO 中文信息会乱码
        //  context.setResponseBody("令牌不存在或失效，请重新认证");
            context.setResponseBody("token is not exit,please auth ...");
        }else{
            //开始验签
            //boolean yn = JwtUtils.validateJWT(token);
            boolean yn = true;
            if (!yn){
                log.info("验签失败");
                context.setSendZuulResponse(false);
                context.setResponseStatusCode(401);
            }else{
                log.info("验签成功！");
            }
        }
        return null;
    }
}
